
/* 
特性与接口的不同点：接口只能规范方法而不能定义方法，但特性可以定义方法作为默认方法，
因为是"默认"，所以对象既可以重新定义方法，也可以不重新定义方法使用默认的方法
*/
trait Compare {
    fn compare(&self, o: &Self)->i8 {
        -1
    }
}

//impl <特性名> for <所实现的类型名>
impl Compare for u32 {
    fn compare(&self, o:&Self) ->i8 {    //新方法
        if &self > &o { 1 }
        else if &self == &o {0}
        else {-1}
    }
}

fn arrMax<T: Compare>(arr: &[T]) ->&T {
    let mut idx = 0;
    let mut i = 0;
    while i < arr.len() {
        if arr[i].compare(&arr[idx]) > 0 {
            idx = i;
        }
        i = i + 1;
    }
    &arr[idx]
}

//----------------------------------------------------

#[derive(Debug)]
struct Point<T> {
    x:T,
    y:T
}

//-----------------------------------------------------------------------------------

trait Descriptive {
    fn describe(&self) -> String {
        String::from("[Object]")
    }
}

struct Person {
    name: String,
    age: u8
}

impl Descriptive for Person {
    //重新定义方法
    /* fn describe(&self) -> String {
        format!("{} {}", self.name, self.age)
    } */
}

fn do_person() {
    let cali = Person {
        name: String::from("Cali"),
        age: 24
    };
    println!("{}", cali.describe());
}

//-----------------------------------------------------------------------------------
struct A {}
impl Descriptive for A {

}
struct B {}
impl Descriptive for B {

}
//特性做返回值只接受实现了该特性的对象做返回值且在同一个函数中所有可能的返回值类型必须完全一样
fn getStructAB(b:bool) ->impl Descriptive {
    if b {
        return B{}  //A{} 错误
    } else {
        B{}
    }
}

//----------------------------------------------------
fn do_base8() {
    //panic!("base7 over!!!!!!!");
    println!("------------------------ do base8 begin -------------------------------------");

    let arr = [3,11,7,10, 6];
    println!("arr max = {}", arrMax(&arr));

    let p1 = Point {x:1, y:2};
    println!("p1 = {:?}", p1);
    let p2 = Point {x:1.4, y:2.1};
    println!("p2 = {:?}", p2);

    /* let arr1 = [3.7,1.7,7.9,10.2, 6.1];
    println!("arr max = {}", arrMax(&arr1)); */

    do_person();
    
    println!("------------------------ do base8 end -------------------------------------");
}
